package estatisticas;
import java.util.LinkedList;


public class GeradorDeEstatisticas {
	
	public static final int NUM_DEZENAS_SORTEADAS_MEGA_SENA		= 6;
	public static final int NUM_DEZENAS_SORTEADAS_DUPLA_SENA	= 6;
	public static final int NUM_DEZENAS_SORTEADAS_QUINA			= 5;
	
	public static final int NUM_DEZENAS_MEGA_SENA 				= 60;
	public static final int NUM_DEZENAS_DUPLA_SENA				= 50;
	public static final int NUM_DEZENAS_QUINA		 			= 80;
	
	public static final int TOTAL_JOGOS_LOTERIA					= 3;
	
	public static int COD_MEGA_SENA 							= 0;
	public static int COD_DUPLA_SENA							= 1;
	public static int COD_QUINA		 							= 2;
	
	private static int[] vetNumeroDezenasJogo;
	private static int[] vetNumeroDezenasSorteio;
	
	private LeitorResultados leitorArquivo;
	private LinkedList<String[]> listaResultadosMegaSena;
	private LinkedList<String[]> listaResultadosDuplaSena;
	
	static 
	{
		COD_MEGA_SENA 								= Principal.COD_MEGA_SENA;
		COD_DUPLA_SENA								= Principal.COD_DUPLA_SENA;
		COD_QUINA		 							= Principal.COD_QUINA;
		
		vetNumeroDezenasJogo 						= new int[TOTAL_JOGOS_LOTERIA];
		
		vetNumeroDezenasJogo[COD_MEGA_SENA]			= NUM_DEZENAS_MEGA_SENA;
		vetNumeroDezenasJogo[COD_DUPLA_SENA]		= NUM_DEZENAS_DUPLA_SENA;
		vetNumeroDezenasJogo[COD_QUINA]				= NUM_DEZENAS_QUINA;
		
		vetNumeroDezenasSorteio 					= new int[TOTAL_JOGOS_LOTERIA];
		
		vetNumeroDezenasSorteio[COD_MEGA_SENA]		= NUM_DEZENAS_SORTEADAS_MEGA_SENA;
		vetNumeroDezenasSorteio[COD_DUPLA_SENA]		= NUM_DEZENAS_SORTEADAS_DUPLA_SENA;
		vetNumeroDezenasSorteio[COD_QUINA]			= NUM_DEZENAS_SORTEADAS_QUINA;
	}

	public GeradorDeEstatisticas () 
	{	
		leitorArquivo = new LeitorResultados();
		listaResultadosMegaSena = new LinkedList<String[]>();
		listaResultadosDuplaSena = new LinkedList<String[]>();
	}
	
	public LinkedList<String[]> obterResultadosMegaSena() 
	{
		if(listaResultadosMegaSena.isEmpty())
			return leitorArquivo.carregarResultadosMegaSena();
		else
			return listaResultadosMegaSena;
	}
	
	public LinkedList<String[]> obterResultadosDuplaSena() 
	{
		if(listaResultadosDuplaSena.isEmpty())
			return leitorArquivo.carregarResultadosDupla();
		else
			return listaResultadosDuplaSena;
	}
	
	public RegistroDezena[] obterAtrasoDezenasConcurso(int concurso, LinkedList<String[]> _listaResultados, int _numDezenasJogo) 
	{
		LinkedList<RegistroDezena> listaReg = obterAtrasoDezenas(concurso, _listaResultados, _numDezenasJogo); 
		
		int[] dezenas = obterDezenasConcurso(concurso, _listaResultados);
		
		RegistroDezena[] atrasoDezenasConcurso = new RegistroDezena[6];
		
		atrasoDezenasConcurso[0] = listaReg.get(dezenas[0] - 1);
		atrasoDezenasConcurso[1] = listaReg.get(dezenas[1] - 1);
		atrasoDezenasConcurso[2] = listaReg.get(dezenas[2] - 1);
		atrasoDezenasConcurso[3] = listaReg.get(dezenas[3] - 1);
		atrasoDezenasConcurso[4] = listaReg.get(dezenas[4] - 1);
		atrasoDezenasConcurso[5] = listaReg.get(dezenas[5] - 1);
		
		return atrasoDezenasConcurso;
	}
	
	public String obterStrAtrasoConcurso(RegistroDezena[] reg) 
	{
		int d1 = reg[0].getAtraso();
		int d2 = reg[1].getAtraso();
		int d3 = reg[2].getAtraso();
		int d4 = reg[3].getAtraso();
		int d5 = reg[4].getAtraso();
		int d6 = reg[5].getAtraso(); 

		return obterStrResultado(d1, d2, d3, d4, d5, d6);
	}
	
	public String obterStrDezenasConcurso(int concurso, LinkedList<String[]> _listaResultados) 
	{
		int d1 = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
		int d2 = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
		int d3 = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
		int d4 = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
		int d5 = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
		int d6 = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_SEXTA_DEZENA]);
		
		String dezenas = obterStrResultado(d1, d2, d3, d4, d5, d6);

		return dezenas;
	}
	
	public int[] obterDezenasConcurso(int concurso, LinkedList<String[]> _listaResultados)
	{
		int[] retorno = new int[6];
		
		retorno[0] = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
		retorno[1] = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
		retorno[2] = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
		retorno[3] = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
		retorno[4] = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
		retorno[5] = Integer.parseInt(_listaResultados.get(concurso-1)[LeitorResultados.COLUNA_SEXTA_DEZENA]);

		return retorno;
	}
	
	public int obterTotalConcursosMegaSena() 
	{
		return listaResultadosMegaSena.size();
	}
	
	public LinkedList<RegistroDezena> obterAtrasoDezenas(int concurso, LinkedList<String[]> _listaResultados, int _codJogo) 
	{	
		LinkedList<RegistroDezena> listaReg = new LinkedList<RegistroDezena>();
		
		for(int i=1; i<=vetNumeroDezenasJogo[_codJogo]; i++)
		{
			RegistroDezena reg = new RegistroDezena(i);
			listaReg.add(reg);
		}
		
		int cont = 0;
		
		for(int i=concurso-2; i>=0; i--)
		{
			int d1=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
			int d2=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
			int d3=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
			int d4=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
			int d5=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
			int d6=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEXTA_DEZENA]);
			
			if(listaReg.get(d1 - 1).getAtraso() == -1)
				listaReg.get(d1 - 1).setAtraso(cont);
			
			if(listaReg.get(d2 - 1).getAtraso() == -1)
				listaReg.get(d2 - 1).setAtraso(cont);
			
			if(listaReg.get(d3 - 1).getAtraso() == -1)
				listaReg.get(d3 - 1).setAtraso(cont);
			
			if(listaReg.get(d4 - 1).getAtraso() == -1)
				listaReg.get(d4 - 1).setAtraso(cont);
			
			if(listaReg.get(d5 - 1).getAtraso() == -1)
				listaReg.get(d5 - 1).setAtraso(cont);
			
			if(listaReg.get(d6 - 1).getAtraso() == -1)
				listaReg.get(d6 - 1).setAtraso(cont);
			
			cont++;
		}
		
		return listaReg;
	}
	
	public ParidadeDezenas obterFrequenciaParidadeDezenas(int concurso, LinkedList<String[]> _listaResultados) 
	{	
		ParidadeDezenas paridadeDezenas = new ParidadeDezenas();
		
		for(int i=0; i<concurso; i++)
		{
			int d1=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
			int d2=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
			int d3=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
			int d4=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
			int d5=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
			int d6=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEXTA_DEZENA]);
			
			paridadeDezenas.processaOcorrencias(d1, d2, d3, d4, d5, d6);
		}
		
		paridadeDezenas.calculaFrequenciasParidade();

		return paridadeDezenas;
	}
	
	public float[] obterFrequenciaDezenas(int concurso, LinkedList<String[]> _listaResultados) 
	{
		float[] frequenciaDezenas = new float[61];
		float[] ocorrenciaDezenas = new float[61];
		
		for(int i=1; i<61; i++)
		{
			frequenciaDezenas[i]=0;
			ocorrenciaDezenas[i]=0;
		}
		
		for(int i=0; i<concurso; i++)
		{
			int d1=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
			int d2=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
			int d3=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
			int d4=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
			int d5=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
			int d6=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEXTA_DEZENA]);
			
			ocorrenciaDezenas[d1]++;
			ocorrenciaDezenas[d2]++;
			ocorrenciaDezenas[d3]++;
			ocorrenciaDezenas[d4]++;
			ocorrenciaDezenas[d5]++;
			ocorrenciaDezenas[d6]++;
		}
		
		for(int i=1; i<61; i++)
			frequenciaDezenas[i] = (100*ocorrenciaDezenas[i])/(6*concurso);
		
		return frequenciaDezenas;
	}
	
	public LinkedList<RegistroDezena> obterRegistroDezenas(int concurso, LinkedList<String[]> _listaResultados, int _codJogo) 
	{
		LinkedList<RegistroDezena> listaReg = new LinkedList<RegistroDezena>();
		
		for(int i=1; i<=vetNumeroDezenasJogo[_codJogo]; i++)
		{
			RegistroDezena reg = new RegistroDezena(i);
			listaReg.add(reg);
		}
		
		for(int i=0; i<concurso; i++)
		{
			int d1=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
			int d2=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
			int d3=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
			int d4=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
			int d5=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
			int d6=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEXTA_DEZENA]);
			
			listaReg.get(d1 - 1).incrementarOcorrenciasDezena();
			listaReg.get(d2 - 1).incrementarOcorrenciasDezena();
			listaReg.get(d3 - 1).incrementarOcorrenciasDezena();
			listaReg.get(d4 - 1).incrementarOcorrenciasDezena();
			listaReg.get(d5 - 1).incrementarOcorrenciasDezena();
			listaReg.get(d6 - 1).incrementarOcorrenciasDezena();
		}
		
		for(int i=1; i<=vetNumeroDezenasJogo[_codJogo]; i++)
			listaReg.get(i-1).setFrequenciaOcorrencia((100*listaReg.get(i - 1).getOcorrenciasDezena())/(6*concurso));
		
		return listaReg;
	}
	
	public int[] obterOcorrenciasDezenas(int concurso, LinkedList<String[]> _listaResultados) 
	{
		int[] ocorrenciaDezenas = new int[61];
		
		for(int i=1; i<61; i++)
			ocorrenciaDezenas[i]=0;
		
		for(int i=0; i<concurso; i++)
		{
			int d1=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_PRIMEIRA_DEZENA]);
			int d2=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEGUNDA_DEZENA]);
			int d3=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_TERCEIRA_DEZENA]);
			int d4=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUARTA_DEZENA]);
			int d5=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_QUINTA_DEZENA]);
			int d6=Integer.parseInt(_listaResultados.get(i)[LeitorResultados.COLUNA_SEXTA_DEZENA]);
			
			ocorrenciaDezenas[d1]++;
			ocorrenciaDezenas[d2]++;
			ocorrenciaDezenas[d3]++;
			ocorrenciaDezenas[d4]++;
			ocorrenciaDezenas[d5]++;
			ocorrenciaDezenas[d6]++;
		}
		
		return ocorrenciaDezenas;
	}
	
	public int obterTotalDezenasJogo(int _codJogo)
	{
		return vetNumeroDezenasJogo[_codJogo];
	}	                     
	
	public String getNomeColuna(int colunaDezena)
	{
		String numeralOrdinal= "";
		
		switch(colunaDezena) {
			case 2:
				numeralOrdinal="primeira";
				break;
			case 3:
				numeralOrdinal="segunda";
				break;
			case 4:
				numeralOrdinal="terceira";
				break;
			case 5:
				numeralOrdinal="quarta";
				break;
			case 6:
				numeralOrdinal="quinta";
				break;
			case 7:
				numeralOrdinal="sexta";
		}
		
		return numeralOrdinal;
	}
	
	public int[] obterResultadoComparacao(String strResultado, String _strResultado) 
	{
		int[] ret = new int[3];
		
		ret[0] = 0;
		ret[1] = 0;
		ret[2] = 0;
		
		String[] resultados = strResultado.split(" ");
		String[] _resultados = _strResultado.split(" ");
		
		int d1 = Integer.valueOf(resultados[0]);
		int d2 = Integer.valueOf(resultados[1]);
		int d3 = Integer.valueOf(resultados[2]);
		int d4 = Integer.valueOf(resultados[3]);
		int d5 = Integer.valueOf(resultados[4]);
		int d6 = Integer.valueOf(resultados[5]);
		
		int _d1 = Integer.valueOf(_resultados[0]);
		int _d2 = Integer.valueOf(_resultados[1]);
		int _d3 = Integer.valueOf(_resultados[2]);
		int _d4 = Integer.valueOf(_resultados[3]);
		int _d5 = Integer.valueOf(_resultados[4]);
		int _d6 = Integer.valueOf(_resultados[5]);
		
		int numeroAcertos = 0;
		
		if(_d1==d1 || _d1==d2 || _d1==d3 || _d1==d4 || _d1==d5 || _d1==d6)
			numeroAcertos++;
		
		if(_d2==d1 || _d2==d2 || _d2==d3 || _d2==d4 || _d2==d5 || _d2==d6)
			numeroAcertos++;
		
		if(_d3==d1 || _d3==d2 || _d3==d3 || _d3==d4 || _d3==d5 || _d3==d6)
			numeroAcertos++;
		
		if(_d4==d1 || _d4==d2 || _d4==d3 || _d4==d4 || _d4==d5 || _d4==d6)
			numeroAcertos++;
		
		if(_d5==d1 || _d5==d2 || _d5==d3 || _d5==d4 || _d5==d5 || _d5==d6)
			numeroAcertos++;
		
		if(_d6==d1 || _d6==d2 || _d6==d3 || _d6==d4 || _d6==d5 || _d6==d6)
			numeroAcertos++;
		
		if(numeroAcertos == 6)
			ret[0]++;
		else
		if(numeroAcertos == 5)
			ret[1]++;
		else
		if(numeroAcertos == 4)
			ret[2]++;
		
		return ret;
	}
	
	public String obterStrResultado(int _d1, int _d2, int _d3, int _d4, int _d5, int _d6) 
	{
		String ret = "";
		
		String strDezena;
		
		strDezena = String.valueOf(_d1);
		if(_d1 < 10 && _d1 >= 0)
			ret += "0";
		
		ret += strDezena + " ";
		
		strDezena = String.valueOf(_d2);
		if(_d2 < 10 && _d2 >= 0)
			ret += "0";
		
		ret += strDezena + " ";
		
		strDezena = String.valueOf(_d3);
		if(_d3 < 10 && _d3 >= 0)
			ret += "0";
		
		ret += strDezena + " ";
		
		strDezena = String.valueOf(_d4);
		if(_d4 < 10 && _d4 >= 0)
			ret += "0";
		
		ret += strDezena + " ";
		
		strDezena = String.valueOf(_d5);
		if(_d5 < 10 && _d5 >= 0)
			ret += "0";
		
		ret += strDezena + " ";
		
		strDezena = String.valueOf(_d6);
		if(_d6 < 10 && _d6 >= 0)
			ret += "0";
		
		ret += strDezena;
		
		return ret;
	}
	
	public double obterTotalCobinacoesMegaSena(int n, int p)
	{
		if(p > 6 && p < 1)
			return -1;
		
		if(n < p)
			return -1;
		
		if(n == 0)
			return -1;
		
		if(60 - n < 6 - p)
			return -1;
		
		if(60 - n == 0)
			return -1;
		
		return obterCombinacaoDeNTomadosPaP(60,6)/(obterCombinacaoDeNTomadosPaP(60 - n, 6 - p)*obterCombinacaoDeNTomadosPaP(n,p));
	}
	
	public double obterTotalCobinacoesDuplaSena(int n, int p)
	{
		if(p > 6 && p < 1)
			return -1;
		
		if(n < p)
			return -1;
		
		if(n == 0)
			return -1;
		
		if(50 - n < 6 - p)
			return -1;
		
		if(50 - n == 0)
			return -1;
		
		return obterCombinacaoDeNTomadosPaP(50,6)/(obterCombinacaoDeNTomadosPaP(50 - n, 6 - p)*obterCombinacaoDeNTomadosPaP(n,p));
	}
	
	public double obterTotalCobinacoesQuina(int n, int p)
	{
		if(p > 5 && p < 1)
			return -1;
		
		if(n < p)
			return -1;
		
		if(n == 0)
			return -1;
		
		if(80 - n < 5 - p)
			return -1;
		
		if(80 - n == 0)
			return -1;
		
		return obterCombinacaoDeNTomadosPaP(80,5)/(obterCombinacaoDeNTomadosPaP(80 - n, 5 - p)*obterCombinacaoDeNTomadosPaP(n,p));
	}
	
	public double obterCombinacaoDeNTomadosPaP(int n, int p)
	{
		double ret = 1;
		
		if(p > n)
			return -1;
		
		for(int i = n; i > p; i--)
			ret = ret * i;
		
		ret = ret/fatorial(n-p);
		
		return ret;
	}
	
	public double fatorial(int n)
	{
		if(n < 0)
			return -1;
		
		if(n == 0)
			return 1;
		else
			return n * fatorial(n - 1);
	}

	public LeitorResultados getLeitorArquivo() 
	{
		return leitorArquivo;
	}

	public void setLeitorArquivo(LeitorResultados leitorResultadosArquivo) 
	{
		this.leitorArquivo = leitorResultadosArquivo;
	}

	public LinkedList<String[]> getListaResultadosMegaSena() {
		return listaResultadosMegaSena;
	}

	public void setListaResultadosMegaSena(
			LinkedList<String[]> listaResultadosMegaSena) {
		this.listaResultadosMegaSena = listaResultadosMegaSena;
	}

	public void setListaResultadosDuplaSena(LinkedList<String[]> listaResultadosDuplaSena) {
		this.listaResultadosDuplaSena = listaResultadosDuplaSena;
	}

	public LinkedList<String[]> getListaResultadosDuplaSena() {
		return listaResultadosDuplaSena;
	}
}
